package com.hundsun.cprs.yyt.service.goods.service.impl;

import com.hundsun.cprs.yyt.common.base.BaseService;
import com.hundsun.cprs.yyt.common.enums.EnumAreaCode;
import com.hundsun.cprs.yyt.common.enums.EnumBusinessCode;
import com.hundsun.cprs.yyt.common.exception.ServiceCodeException;
import com.hundsun.cprs.yyt.service.goods.dao.GoodsDao;
import com.hundsun.cprs.yyt.service.goods.dao.GoodsImageDao;
import com.hundsun.cprs.yyt.service.goods.dao.GoodsWithAreaDao;
import com.hundsun.cprs.yyt.service.goods.domain.GoodsImage;
import com.hundsun.cprs.yyt.service.goods.domain.GoodsSpecs;
import com.hundsun.cprs.yyt.service.goods.domain.query.GoodsQuery;
import com.hundsun.cprs.yyt.service.goods.dto.GoodsAreaInfo;
import com.hundsun.cprs.yyt.service.goods.dto.GoodsInfo;
import com.hundsun.cprs.yyt.service.goods.enums.EnumQuoteRewardPolicy;
import com.hundsun.cprs.yyt.service.goods.service.GoodsService;
import com.hundsun.cprs.yyt.service.goods.service.GoodsSkuService;
import com.hundsun.cprs.yyt.util.DoubleUtil;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class GoodsServiceImpl extends BaseService implements GoodsService {

    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private GoodsImageDao goodsImageDao;
    @Autowired
    private GoodsSkuService goodsSkuService;
    @Autowired
    private GoodsWithAreaDao goodsWithAreaDao;

    @Override
    @Transactional
    public void createGoods(GoodsInfo goodsInfo) {
        try{
            //1.校验参数
            validateParam(goodsInfo);
            //2.金额转换
            changeMoney(goodsInfo);
            //3.新增商品
            initParam(goodsInfo);
            goodsDao.insert(goodsInfo);
            //4.新增商品图片
            createGoodsImage(goodsInfo);

        }catch (ServiceCodeException e){
            logger.error("商品:"+goodsInfo.getGoodsName()+",新增出错：" + e);
            throw e;
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    @Caching(
        evict = {
            @CacheEvict(value="YYT:AREA:GOODS",key="'WHOLESALE_AREA:' + new String(#goodsInfo.id)"),
            @CacheEvict(value="YYT:AREA:GOODS",key="'RETAIL_AREA:' + new String(#goodsInfo.id)"),
        }
    )
    @Transactional
    public void updateGoods(GoodsInfo goodsInfo) {
        try{
            //1.校验参数
            validateParam(goodsInfo);
            //2.金额转换
            changeMoney(goodsInfo);
            //3.修改商品基本信息
            goodsDao.updateByPrimaryKeySelective(goodsInfo);
            //4.清除原有的商品图片
            delGoodsImage(goodsInfo);
            //5.新增商品图片
            createGoodsImage(goodsInfo);
            //6.修改零售区sku的零售价
            updateRetaileSku(goodsInfo);

        }catch (ServiceCodeException e){
            logger.error("商品:"+goodsInfo.getGoodsName()+",修改出错：" + e);
            throw e;
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    @Caching(
        evict = {
            @CacheEvict(value="YYT:AREA:GOODS",key="'WHOLESALE_AREA:' + new String(#goodsInfo.id)"),
            @CacheEvict(value="YYT:AREA:GOODS",key="'RETAIL_AREA:' + new String(#goodsInfo.id)"),
        }
    )
    @Transactional
    public void deleteGoods(int goodsId) {
        //删除商品前先校验该商品是否上架，如果存在已上架的商品则不允许删除
        int count = goodsWithAreaDao.goodsCount(goodsId);
        if (count > 0){
            //该商品存在上架记录，不允许删除
            throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1511.getErrorNo(),EnumBusinessCode.BUSINESS_1511.getErrorInfo());
        }
        goodsDao.deleteByPrimaryKey(goodsId);
    }

    @Override
    public void queryGoodsByPage(GoodsQuery query) {
        List<GoodsInfo> goodsList = goodsDao.queryGoodsPage(query);
        query.compatible(goodsList);
    }
    
    @Override
    public List<GoodsInfo> queryGoodsByList(GoodsQuery query) {
        query.onlyReturnList();
        return goodsDao.queryGoodsPage(query);
    }

    @Override
    public GoodsInfo selectGoodsInfoById(int goodsId,String areaCode) {
        //获取商品spu属性
        GoodsAreaInfo goodsAreaInfo = goodsWithAreaDao.selectByAreaCodeAndGoodsId(areaCode, goodsId);
        if (goodsAreaInfo == null){
           return null;
        }
        GoodsInfo goodsInfo = goodsAreaInfo.getGoods();
        goodsInfo.setPublishTime(goodsAreaInfo.getPublishTime());//冗余数据,兼容原对象返回
        goodsInfo.setStatus(goodsAreaInfo.getGoodsStatus());
        goodsInfo.setTopShow(goodsAreaInfo.getTopShow());
        
        //获取商品sku属性,从规格表中获取
        List<GoodsSpecs> goodsSpecsList = goodsSkuService.selectGoodsSpecsList(goodsId,areaCode);
        goodsInfo.setSkus(goodsSpecsList);
        //获取商品轮播图
        List<GoodsImage> goodsImageList = goodsImageDao.selectImageList(goodsInfo.getId());
        goodsInfo.setImageList(goodsImageList);
        return goodsInfo;
    }
    
    @Override
    @Cacheable(value="YYT:AREA:GOODS",key="#areaCode.toUpperCase() + ':' + new String(#goodsId)")
    public GoodsInfo selectGoodsInfoByIdFromCache(int goodsId, String areaCode) {
        return selectGoodsInfoById(goodsId,areaCode);
    }

    protected void updateRetaileSku(GoodsInfo goodsInfo){
        List<GoodsSpecs> goodsSpecsList = goodsSkuService.selectGoodsSpecsList(goodsInfo.getId(),EnumAreaCode.RETAIL_AREA.getCode());
        if (!goodsSpecsList.isEmpty()) {
            for (GoodsSpecs goodsSpecs:goodsSpecsList) {
                if (goodsSpecs != null && goodsInfo.getCostPrice().compareTo(goodsSpecs.getGoodsPrice())!=0) {
                    GoodsSpecs sku = new GoodsSpecs();
                    sku.setId(goodsSpecs.getId());
                    sku.setGoodsPrice(goodsInfo.getCostPrice());
                    sku.setVersion(goodsSpecs.getVersion());
                    goodsSkuService.updateSkuRecord(sku);
                }
            }
        }
    }

    protected void validateParam(GoodsInfo goodsInfo){
        Validate.notNull(goodsInfo.getClassifyId(),"商品分类必填");
        Validate.notNull(goodsInfo.getGoodsName(),"商品名称必填");
        Validate.notNull(goodsInfo.getGoodsCode(),"商品编号必填");
        Validate.notNull(goodsInfo.getImageList(),"商品图片必填");
        Validate.notNull(goodsInfo.getCostPrice(),"商品折扣价必填");
        Validate.notNull(goodsInfo.getOrganizationId(),"供应商必填");

    }

    protected void initParam(GoodsInfo goodsInfo){
    	//填充业务默认值
        goodsInfo.setIsDeleted("N");
        if(goodsInfo.getQuotaRewardPolicy() == null) {
        	goodsInfo.setQuotaRewardPolicy(EnumQuoteRewardPolicy.NONE.ordinal());
        }
        if (goodsInfo.getQuotaRewardAmount() == null) {
			goodsInfo.setQuotaRewardAmount(BigDecimal.ZERO.intValue());
		}
    }

    protected void changeMoney(GoodsInfo goodsInfo){
        if (goodsInfo.getGoodsPrice() != null){
            goodsInfo.setGoodsPrice(DoubleUtil.mul(goodsInfo.getGoodsPrice(),100D));
        }
        goodsInfo.setCostPrice(DoubleUtil.mul(goodsInfo.getCostPrice(),100D));
    }

    protected void createGoodsImage(GoodsInfo goodsInfo){
        for (GoodsImage goodsImage:goodsInfo.getImageList()){
            goodsImage.setGoodsId(goodsInfo.getId());
            goodsImageDao.insert(goodsImage);
        }
    }

    protected void delGoodsImage(GoodsInfo goodsInfo){
        //查找到商品的所有图片,并删除
        List<GoodsImage> goodsImageList = goodsImageDao.selectImageList(goodsInfo.getId());
        if (!goodsImageList.isEmpty()){
            for (GoodsImage goodsImage:goodsImageList){
                goodsImageDao.deleteByPrimaryKey(goodsImage.getId());
            }
        }
    }

    @Override
    public List<GoodsInfo> selectGoodsByGoodsCode(String goodsCode) {
        GoodsQuery query = new GoodsQuery();
        query.setGoodsCode(goodsCode);
        query.onlyReturnList();
        return goodsDao.queryGoodsPage(query);
    }

    @Override
    public void queryAreaGoodsList(GoodsQuery query) {
        List<GoodsInfo> goodsInfoList = goodsDao.queryAreaGoodsList(query);
        query.compatible(goodsInfoList);
    }

    @Override
    public void updateGoodsStatus(Integer goodsId, String status) {
        GoodsInfo goodsInfo = new GoodsInfo();
        goodsInfo.setId(goodsId);
        goodsInfo.setStatus(status);
        goodsDao.updateByPrimaryKeySelective(goodsInfo);
    }

    @Override
    public void queryUnBindGoodsList(GoodsQuery query) {
        List<GoodsInfo> goodsInfoList = goodsDao.queryUnBindGoodsList(query);
        query.compatible(goodsInfoList);
    }

    /**
     * 获取商品基本信息（不包含sku信息）
     * 重载方法
     *
     * */
    @Override
    public GoodsInfo selectGoodsInfoById(int goodsId) {
        //获取商品spu属性
        GoodsInfo goodsInfo = goodsDao.selectByPrimaryKey(goodsId);
        if (goodsInfo==null){
            throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1102.getErrorNo(),EnumBusinessCode.BUSINESS_1102.getErrorInfo());
        }
        //获取商品轮播图
        List<GoodsImage> goodsImageList = goodsImageDao.selectImageList(goodsInfo.getId());
        goodsInfo.setImageList(goodsImageList);
        return goodsInfo;
    }

    @Override
    public void fillGoodsImageList(List<GoodsInfo> goodsInfoList) {
        for (GoodsInfo goodsInfo:goodsInfoList){
            List<GoodsImage> goodsImageList = goodsImageDao.selectImageList(goodsInfo.getId());
            goodsInfo.setImageList(goodsImageList);
        }
    }

    @Override
    public void queryGoodsPlateList(GoodsQuery query) {
        List<GoodsInfo> goodsInfoList = goodsDao.queryGoodsPlateList(query);
        query.compatible(goodsInfoList);
    }

    @Override
    public void queryGoodsClassifyList(GoodsQuery query) {
        List<GoodsInfo> goodsInfoList = goodsDao.queryGoodsClassifyList(query);
        query.compatible(goodsInfoList);
    }

    @Override
    @Caching(
        evict = {
            @CacheEvict(value="YYT:AREA:GOODS",key="'WHOLESALE_AREA:' + new String(#goods.id)"),
            @CacheEvict(value="YYT:AREA:GOODS",key="'RETAIL_AREA:' + new String(#goods.id)"),
        }
    )
    @Transactional
    public void modifyGoods(GoodsInfo goods) {
        goodsDao.updateByPrimaryKeySelective(goods);
    }

    @Override
    @Cacheable(value="YYT:GOODS:INFO",key="#goodsCode")
    public GoodsInfo getGoodsInfoByGoodsCodeFromCache(String goodsCode) {
        List<GoodsInfo> goodsInfos = this.selectGoodsByGoodsCode(goodsCode);
        if (CollectionUtils.isEmpty(goodsInfos)){
            return null;
        }else {
            return goodsInfos.get(0);
        }
    }
}
